package com.moveme.examples.ninjafruitlike;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.jbox2d.callbacks.ContactImpulse;
import org.jbox2d.callbacks.ContactListener;
import org.jbox2d.collision.Manifold;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.contacts.Contact;
import org.jbox2d.testbed.framework.DebugDrawJ2D;
import org.jbox2d.testbed.framework.TestPanel;
import org.jbox2d.testbed.framework.TestbedSettings;

public class GameScreen extends TestPanel implements ContactListener {

    /**
     * -1 to 1 (left to right)
     */
    protected float normalizedPointerX;

    /**
     * -1 to 1 (bottom to top)
     */
    protected float normalizedPointerY;

    private static final int POINTER_WIDTH = 25;

    private static final int POINTER_HEIGHT = 25;

    protected List<Body> readyToJump = new ArrayList<Body>();

    /**
     * Step
     */
    public static final long STEP = 1000 / 60;

    private Timer gameLoopTimer;
    
    public GameScreen() {
        this(new TestbedSettings());
    }

    public GameScreen(TestbedSettings testSettings) {
        super(new TestbedSettings());
        this.setBackground(new Color(255, 255, 255));
        Vec2 gravity = new Vec2(0, -10);
        World gameWorld = new World(gravity, true);
        DebugDrawJ2D debug = new DebugDrawJ2D(this);
        gameWorld.setDebugDraw(debug);

        // Enemy Body definition
        BodyDef enBodyDef = new BodyDef();
        enBodyDef.type = BodyType.DYNAMIC;
        enBodyDef.position = new Vec2(0, 0);
        // Enemy Polygon definition
        PolygonShape enPolygonShape = new PolygonShape();
        enPolygonShape.setAsBox(1, 1);
        // Body
        Body enBody = gameWorld.createBody(enBodyDef);
        enBody.createFixture(enPolygonShape, 1);
        enBody.setUserData("en1");

        // Floor definition
        BodyDef floor = new BodyDef();
        floor.type = BodyType.KINEMATIC;
        floor.position = new Vec2(0, -10);
        Body floorBody = gameWorld.createBody(floor);

        PolygonShape floorPoly = new PolygonShape();
        floorPoly.setAsBox(30, 0.1f);
        floorBody.createFixture(floorPoly, 1);
        floorBody.setUserData("floor");

        gameWorld.setContactListener(this);
        // Create game loop
        GameLoop loop = new GameLoop(this, gameWorld);
        gameLoopTimer = new Timer();
        gameLoopTimer.scheduleAtFixedRate(loop, 0, STEP);

    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2D = (Graphics2D) g; // cast to 2D
        int pointerX = (int) (this.normalizedPointerX * this.getWidth() / 2)
                + this.getWidth() / 2;
        int pointerY = (int) ((-1) * this.normalizedPointerY * this.getHeight() / 2)
                + this.getHeight() / 2;
        g2D.setColor(new Color(255, 0, 0));
        g2D.drawArc(pointerX - POINTER_WIDTH, pointerY - POINTER_HEIGHT,
                2 * POINTER_WIDTH, 2 * POINTER_HEIGHT, 0, 360);

    }

    @Override
    public void update(Graphics g) {
        // TODO Auto-generated method stub
        super.update(g);
    }

    public static void main(String[] args) {
        TestbedSettings testSettings = new TestbedSettings();
        GameScreen gameScreen = new GameScreen(testSettings);
        gameScreen.start();
    }

    @Override
    public void beginContact(Contact arg0) {
        System.out.println("tocou");
        readyToJump.add(arg0.getFixtureA().getBody());

    }

    @Override
    public void endContact(Contact arg0) {
        System.out.println("parou de tocar");
        readyToJump.remove(arg0.getFixtureA().getBody());
        System.out.println(arg0.getFixtureA().getBody().getUserData());
        System.out.println(arg0.getFixtureB().getBody().getUserData());
    }

    @Override
    public void postSolve(Contact arg0, ContactImpulse arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void preSolve(Contact arg0, Manifold arg1) {
        // TODO Auto-generated method stub

    }

}

class GameLoop extends TimerTask {

    private GameScreen screen;

    private World gameWorld;

    public GameLoop(GameScreen screen, World world) {
        this.screen = screen;
        this.gameWorld = world;
    }

    @Override
    public void run() {
        this.gameWorld.step(GameScreen.STEP, 6, 2);
        Body oneBody = this.gameWorld.getBodyList();
        if (oneBody != null) {
            do {
                if (oneBody.getUserData().toString().startsWith("en")) {
                    System.out.println(oneBody.getUserData() + ":"
                            + oneBody.getPosition());
                }
                oneBody = oneBody.getNext();
            } while (oneBody != null);
        }
        for (Iterator iterator = this.screen.readyToJump.iterator(); iterator
                .hasNext();) {
            Body bodyToJump = (Body) iterator.next();
            bodyToJump.applyLinearImpulse(new Vec2(0, 200),
                    bodyToJump.getWorldCenter());
        }
        this.gameWorld.drawDebugData();
    }

}